﻿using System;
using System.Net;
using RestSharp;

namespace INdTFramework.Http
{
    /// <summary>
    /// HttpRestRequest extends the RestRequest to provide client different interface to
    /// handle successfull and failed requests. In pratice, all connections that succeed
    /// and return result from are are considered succesful response, otherwise, are considered
    /// failed. As this class extends RestRequest, more complex scenarios like connection on
    /// retry on authentication failure can be implemented too.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="E"></typeparam>
    public abstract class HttpRestRequest<T, E> : RestRequest
    {
        public Action<IRestResponse, RestRequestAsyncHandle> Callback { get; set; }
        protected Action<T> _successResponse;
        protected Action<E> _errorResponse;

        /// <summary>
        /// Overloaded constructor
        /// </summary>
        /// <param name="resource">Relative path to REST resource</param>
        /// <param name="method">HTTP method to perform request</param>
        /// <param name="successResponse">Delegate method for success</param>
        /// <param name="errorResponse">Delegate method for fail</param>
        public HttpRestRequest(String resource, RestSharp.Method method, Action<T> successResponse, Action<E> errorResponse)
            : base(resource, method)
        {
            Callback += PreProcessResponse;
            this._successResponse = successResponse;
            this._errorResponse = errorResponse;
        }

        /// <summary>
        /// Helper method to add parameters to request. If null, the paramenter adding
        /// is ignored.
        /// </summary>
        /// <param name="paramName"></param>
        /// <param name="value"></param>
        public void AddParameterIfNotNull(String paramName, Object value)
        {
            if (value != null)
            {
                AddParameter(paramName, value);
            }
        }

        /// <summary>
        /// Internal delegate to first response handling. If successful the request call the abstract
        /// method ProcessSuccessRequest. Otherwise ProcessFailedRequest is called. 
        /// 
        /// </summary>
        /// <param name="response">Raw RestSharp response instance</param>
        /// <param name="handle">Handle instance of this request.</param>
        public void PreProcessResponse(IRestResponse response, RestRequestAsyncHandle handle)
        {
            if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Created)
            {
                ProcessSuccessRequest(response, handle);
            }
            else
            {
                ProcessFailedRequest(response, handle);
            }
        }

        /// <summary>
        /// Abstract method to handle succesfull responses
        /// </summary>
        /// <param name="response"></param>
        /// <param name="handle"></param>
        protected abstract void ProcessSuccessRequest(IRestResponse response, RestRequestAsyncHandle handle);

        /// <summary>
        /// Abstract method to handle fail responses
        /// 
        /// </summary>
        /// <param name="response"></param>
        /// <param name="handle"></param>
        protected abstract void ProcessFailedRequest(IRestResponse response, RestRequestAsyncHandle handle);
    }
}
